/*
 * // +-------------------------------------------------------------------------------------------------
 * // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
 * // +-------------------------------------------------------------------------------------------------
 * // |                             独在异乡为异客         每逢佳节倍思亲
 * // +-------------------------------------------------------------------------------------------------
 * // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
 * // +-------------------------------------------------------------------------------------------------
 */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------


package wang.encoding.mroot.plugin.ueditor.upload;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

import com.qiniu.common.Zone;
import com.qiniu.storage.Configuration;
import org.apache.commons.io.FileUtils;

import org.springframework.util.ClassUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import wang.encoding.mroot.plugin.ueditor.define.AppInfo;
import wang.encoding.mroot.plugin.ueditor.define.BaseState;
import wang.encoding.mroot.plugin.ueditor.define.FileType;
import wang.encoding.mroot.plugin.ueditor.define.State;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import wang.encoding.mroot.plugin.ueditor.util.DateUtil;

import javax.servlet.http.HttpServletRequest;


/**
 * 存储管理
 *
 * @author ErYang
 */
public class StorageManager {

    private static final int BUFFER_SIZE = 8192;

    public static String accessKey;
    public static String secretKey;
    public static String baseUrl;
    public static String bucket;
    public static String uploadDirPrefix;
    public static Zone zone;

    public static Boolean uploadLocal;

    /**
     * 保存文件
     *
     * @param data byte[]
     * @param path String
     * @return State
     */
    static State saveBinaryFile(final byte[] data, final String path) {
        State state;
        String key = uploadDirPrefix + getFileName(path);
        try {
            String uploadToken = Auth.create(accessKey, secretKey).uploadToken(bucket);
            Response response = new UploadManager(new Configuration(zone)).put(data, key, uploadToken);
            int statusCode = 200;
            if (statusCode == response.statusCode) {
                state = new BaseState(true);
                state.putInfo("size", (long) data.length);
                state.putInfo("title", path);
                state.putInfo("url", baseUrl + key);
            } else {
                state = new BaseState(false, AppInfo.IO_ERROR);
            }
        } catch (QiniuException e) {
            state = new BaseState(false, AppInfo.IO_ERROR);
        }
        return state;
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 保存
     *
     * @param is      InputStream
     * @param path    String
     * @param maxSize long
     * @return State
     */
    static State saveFileByInputStream(final InputStream is, final String path, final long maxSize) {
        State state;
        File tmpFile = getTmpFile();

        byte[] dataBuf = new byte[2048];
        BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);

        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE);
            int count;
            while ((count = bis.read(dataBuf)) != -1) {
                bos.write(dataBuf, 0, count);
            }
            bos.flush();
            bos.close();
            if (tmpFile.length() > maxSize) {
                boolean flag = tmpFile.delete();
                return new BaseState(false, AppInfo.MAX_SIZE);
            }
            state = saveTmpFile(tmpFile, path);
            if (!state.isSuccess()) {
                boolean flag = tmpFile.delete();
            }
            return state;
        } catch (IOException ignored) {
        }
        return new BaseState(false, AppInfo.IO_ERROR);
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 保存
     *
     * @param is   InputStream
     * @param path String
     * @return State
     */
    public static State saveFileByInputStream(final InputStream is, final String path) {
        State state;
        File tmpFile = getTmpFile();
        byte[] dataBuf = new byte[2048];
        BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE);
            int count;
            while ((count = bis.read(dataBuf)) != -1) {
                bos.write(dataBuf, 0, count);
            }
            bos.flush();
            bos.close();
            state = saveTmpFile(tmpFile, path);
            if (!state.isSuccess()) {
                boolean flag = tmpFile.delete();
            }
            return state;
        } catch (IOException ignored) {
        }
        return new BaseState(false, AppInfo.IO_ERROR);
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 临时文件
     *
     * @return File
     */
    private static File getTmpFile() {
        File tmpDir = FileUtils.getTempDirectory();
        String tmpFileName = (Math.random() * 10000 + "").replace(".", "");
        return new File(tmpDir, tmpFileName);
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 保存临时文件
     *
     * @param tmpFile File
     * @param path    String
     * @return State
     */
    private static State saveTmpFile(final File tmpFile, final String path) {
        State state;
        try {
            if (uploadLocal) {
                String name = getFileName(path);
                String key = "assets/upload/" + (new SimpleDateFormat("yyyyMMdd").format(new Date())) + "/" + name;
                String filePath = Objects.requireNonNull(ClassUtils.getDefaultClassLoader().getResource("")).getPath();
                File file = new File(filePath + "static/" + key);
                if (!file.getParentFile().exists()) {
                    boolean flag = file.getParentFile().mkdirs();
                }
                try {
                    BufferedInputStream input = new BufferedInputStream(new FileInputStream(tmpFile));
                    BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file));
                    int read = input.read();
                    while (read != -1) {
                        output.write(read);
                        read = input.read();
                    }
                    input.close();
                    output.close();
                } catch (IOException ignored) {
                }
                state = new BaseState(true);
                state.putInfo("size", tmpFile.length());
                state.putInfo("title", "/" + key);
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String baseUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
                state.putInfo("url", baseUrl + "/" + key);
//                try {
//                    Image image = ImageIO.read(file);
//                    // 上传为图片保存在到Picture表,用于在线图片浏览
//                    if (null != image) {
//                        IPictureService pictureService = (IPictureService) SpringUtil.getBean("pictureServiceImpl");
//                        Picture pic = new Picture();
//                        pic.setTitle("图片");
//                        pic.setName(name);
//                        pic.setPath("/" + key);
//                        pic.setRemark("百度富文本上传");
//                        pic.setType(Picture.TYPE_BAIDU_UPLOAD);
//                        pictureService.insertOrUpdate(pic);
//                    }
//                } catch (Exception ignored) {
//                }
            } else {
                String key = uploadDirPrefix + getFileName(path);
                String uploadToken = Auth.create(accessKey, secretKey).uploadToken(bucket);
                Response response = new UploadManager(new Configuration(zone)).put(tmpFile, key, uploadToken);
                int statusCode = 200;
                if (statusCode == response.statusCode) {
                    state = new BaseState(true);
                    state.putInfo("size", tmpFile.length());
                    state.putInfo("title", key);
                    state.putInfo("url", baseUrl + "/" + key);
                } else {
                    state = new BaseState(false, AppInfo.IO_ERROR);
                }
            }
        } catch (QiniuException e) {
            state = new BaseState(false, AppInfo.IO_ERROR);
        }
        return state;
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 文件名称
     *
     * @param fileName String
     * @return String
     */
    private static String getFileName(final String fileName) {
        String suffix = FileType.getSuffixByFilename(fileName);
        return DateUtil.formatDate(new Date(), DateUtil.DATE) + (int) (Math.random() * 9000 + 1000) + suffix;
    }

    // -------------------------------------------------------------------------------------------------

}

// -----------------------------------------------------------------------------------------------------

// End StorageManager class

/* End of file StorageManager.kt */
/* Location: ./src/main/kotlin/wang/encoding/mroot/plugin/ueditor/upload/StorageManager.kt */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                           ErYang出品 属于小极品  O(∩_∩)O~~   共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------
